//
// Created by HP on 2024/1/13.
//

#include "aurora_font.h"

uint8_t __attribute__((section(".ccmram"))) buff_num[13][256];
Aurora_Font::Aurora_Font(Eflash_Driver *eflash_s){
     __g_xbf_hd = {
            .min = 0x0020,
            .max = 0x9fa0,
            .bpp = 1,
    };
    line_height = 39;
    eflash = eflash_s;
    num_flag = 0;
    for(uint8_t i = 0;i<10;i++){
        getfontData(font_size_small,48 + i);
        memcpy(buff_num[i],buff,256);
        font_wnum = font_w;
        font_hnum  = font_h;
        fontofs_ynum = fontofs_y ;
        fontadv_wnum = fontadv_w;
    }
    getfontData(font_size_small,46);
    memcpy(buff_num[10],buff,256);
    font_wdot = font_w;
    font_hdot  = font_h;
    fontofs_ydot = fontofs_y ;
    fontadv_wdot = fontadv_w;


    getfontData(font_size_small,45);
    memcpy(buff_num[11],buff,256);
    font_wdd = font_w;
    font_hdd  = font_h;
    fontofs_ydd = fontofs_y ;
    fontadv_wdd = fontadv_w;

    getfontData(font_size_small,'>');
    memcpy(buff_num[12],buff,256);
    font_warrow = font_w;
    font_harrow  = font_h;
    fontofs_yarrow = fontofs_y ;
    fontadv_warrow = fontadv_w;

    num_flag = 1;
}


void Aurora_Font::addEFLASH_Driver(Eflash_Driver *eflash_s){
    eflash = eflash_s;
}


uint8_t *Aurora_Font::__user_font_getdata(uint32_t offset, int size){
    //如字模保存在SPI FLASH, SPIFLASH_Read(__g_font_buf,offset,size);
    //如字模已加载到SDRAM,直接返回偏移地址即可如:return (uint8_t*)(sdram_fontddr+offset);
    if( size > 256)
        return buff;
    eflash->read_data(offset,buff,size);
    return buff;
}
//获取字符数据
uint8_t *Aurora_Font::getfontData(FONT_SIZE fsize,uint32_t unicode_letter){
    if ( num_flag == 1 && fsize == font_size_small && (unicode_letter >=  48 && unicode_letter <= 57)) {
        font_w = font_wnum;
        font_h = font_hnum;
        fontofs_y = fontofs_ynum;
        fontadv_w = fontadv_wnum;
        return buff_num[unicode_letter - '0'];
    }
    else if ( num_flag == 1 && fsize == font_size_small && unicode_letter == 46) {
        font_w = font_wdot;
        font_h = font_hdot;
        fontofs_y = fontofs_ydot;
        fontadv_w = fontadv_wdot;
        return buff_num[10];
    }
    else if ( num_flag == 1 && fsize == font_size_small && unicode_letter == '-') {
        font_w = font_wdd;
        font_h = font_hdd;
        fontofs_y = fontofs_ydd;
        fontadv_w = fontadv_wdd;
        return buff_num[11];
    }
    else if ( num_flag == 1 && fsize == font_size_small && unicode_letter == '>') {
        font_w = font_warrow;
        font_h = font_harrow;
        fontofs_y = fontofs_yarrow;
        fontadv_w = fontadv_warrow;
        return buff_num[12];
    }

    uint32_t of = (fsize == FONT_SIZE::font_size_big) ? FONT_BIG_BASE_ADDR :
                  (fsize == FONT_SIZE::font_size_middle) ? FONT_MIDDLE_BASE_ADDR : FONT_SMALL_BASE_ADDR; //不同字体的起始地址不同
    line_height = (fsize == FONT_SIZE::font_size_big) ? FONT_BIG_HIGHT :
                  (fsize == FONT_SIZE::font_size_middle) ? FONT_MIDDLE_HIGHT : FONT_SMALL_HIGHT; //不同字体的字高不同
    if( unicode_letter>__g_xbf_hd.max || unicode_letter<__g_xbf_hd.min ) {
        return NULL;
    }
    uint32_t unicode_offset = sizeof(x_header_t)+(  unicode_letter - __g_xbf_hd.min)*4 ;
    uint32_t *p_pos = (uint32_t *)__user_font_getdata(unicode_offset + of, 4);
    if( p_pos[0] != 0 ) {
        uint32_t pos = p_pos[0];
        glyph_dsc_t * gdsc = (glyph_dsc_t*)__user_font_getdata(pos + of, sizeof(glyph_dsc_t));
        font_w   = gdsc->box_w;
        font_h   = gdsc->box_h;
        font_r   = gdsc->r;
        fontofs_x = gdsc->ofs_x;
        fontofs_y = gdsc->ofs_y;
        fontadv_w = gdsc->adv_w;
        font_bpp = __g_xbf_hd.bpp;
        return __user_font_getdata(pos+sizeof(glyph_dsc_t) + of, gdsc->box_w*gdsc->box_h*__g_xbf_hd.bpp/8);
    }
    return NULL;
}

uint8_t *Aurora_Font::getaimimgData(uint32_t offsize,uint8_t *buff,uint32_t len){
    eflash->read_data(AIM_IMG_BASE_ADDR + offsize,buff,len);
    return buff;
}
uint8_t *Aurora_Font::getimgData(uint32_t offsize,uint8_t *buff,uint32_t len){
    eflash->read_data(IMG_BASE_ADDR + offsize,buff,len);
    return buff;
}

void Aurora_Font::set_update_type(uint8_t type){
    _update_type = type;
}
uint8_t Aurora_Font::get_update_type(){
    return _update_type;
}
void Aurora_Font::delete_font_data(FONT_SIZE fsize){
    uint32_t addr = (fsize == FONT_SIZE::font_size_big) ? FONT_BIG_BASE_ADDR :
                    (fsize == FONT_SIZE::font_size_middle) ? FONT_MIDDLE_BASE_ADDR : FONT_SMALL_BASE_ADDR; //不同字体的起始地址不同
    uint8_t i;
    for( i = 0 ;i < 16 ; i++){
        eflash->block_erase(addr);
        addr += eflash->get_block_size();
    }
}

void Aurora_Font::update_font_data(FONT_SIZE fsize,uint32_t addr_offset,uint8_t *data,uint16_t len){
    uint32_t addr = (fsize == FONT_SIZE::font_size_big) ? FONT_BIG_BASE_ADDR :
                    (fsize == FONT_SIZE::font_size_middle) ? FONT_MIDDLE_BASE_ADDR : FONT_SMALL_BASE_ADDR; //不同字体的起始地址不同
    addr += addr_offset;
    eflash->write_data(addr,data,len);
}


void Aurora_Font::set_update_font_type(FONT_SIZE fsize){
    update_font_addr = (fsize == FONT_SIZE::font_size_big) ? FONT_BIG_BASE_ADDR :
                    (fsize == FONT_SIZE::font_size_middle) ? FONT_MIDDLE_BASE_ADDR : FONT_SMALL_BASE_ADDR; //不同字体的起始地址不同
}

void Aurora_Font::set_update_font_data(uint8_t * data,uint16_t len){
    eflash->write_data(update_font_addr,data,len);
    update_font_addr += len;
}


//删除7M地址的空间
void Aurora_Font::delete_aim_img_data(){
    uint32_t addr = AIM_IMG_BASE_ADDR;
    uint8_t i;
    for( i = 0 ;i < 16*7; i++){
        eflash->block_erase(addr);
        addr += eflash->get_block_size();
    }
    usb_printf("aim img data,delete ok\r\n");
    update_aim_img_addr = AIM_IMG_BASE_ADDR;
}
void Aurora_Font::set_update_aim_img_data(uint8_t * data,uint16_t len){
    eflash->write_data(update_aim_img_addr,data,len);
    update_aim_img_addr += len;
}

//删除1M地址的空间
void Aurora_Font::delete_img_data(){
    uint32_t addr = IMG_BASE_ADDR;
    uint8_t i;
    for( i = 0 ;i < 16; i++){
        eflash->block_erase(addr);
        addr += eflash->get_block_size();
    }
    usb_printf("img data,delete ok\r\n");
    update_img_addr = IMG_BASE_ADDR;
}
void Aurora_Font::set_update_img_data(uint8_t * data,uint16_t len){
    eflash->write_data(update_img_addr,data,len);
    update_img_addr += len;
}


/* 加载ui界面参数 */
UI_PARAMETER_STORAGE Aurora_Font::Load_UI_Parameter(){
    UI_PARAMETER_STORAGE param;
    eflash->read_data(PARAMETER_UI_STORAGE_BASE_ADDR,(uint8_t *)&param,sizeof(UI_PARAMETER_STORAGE));
    return param;
}
/* 保存ui界面参数 */
void Aurora_Font::Save_UI_Parameter(UI_PARAMETER_STORAGE ui_param){
    eflash->write_eeprom_byte_data(PARAMETER_UI_STORAGE_BASE_ADDR + 0,ui_param.aim_flag);
    eflash->write_eeprom_byte_data(PARAMETER_UI_STORAGE_BASE_ADDR + 1,ui_param.aim_num);
    eflash->write_eeprom_byte_data(PARAMETER_UI_STORAGE_BASE_ADDR + 2,ui_param.img_flag);
    eflash->write_eeprom_byte_data(PARAMETER_UI_STORAGE_BASE_ADDR + 3,ui_param.aim_flag);
    eflash->write_eeprom_byte_data(PARAMETER_UI_STORAGE_BASE_ADDR + 4,ui_param.font_big_flag);
    eflash->write_eeprom_byte_data(PARAMETER_UI_STORAGE_BASE_ADDR + 5,ui_param.font_middle_flag);
    eflash->write_eeprom_byte_data(PARAMETER_UI_STORAGE_BASE_ADDR + 6,ui_param.font_small_flag);

}

void Aurora_Font::Load_FOC_Parameter(){
    FOC_PARAMETER_STORAGE foc_param;
    eflash->read_data(PARAMETER_FOC_STORAGE_BASE_ADDR,(uint8_t *)&foc_param,sizeof(FOC_PARAMETER_STORAGE));
    ui2foc_msg.foc_param = foc_param;
}
void Aurora_Font::Save_FOC_Parameter(uint8_t sel_M,FOC_PARAMETER_STORAGE foc_param){


    uint32_t start_addr = PARAMETER_FOC_STORAGE_BASE_ADDR;
    if( sel_M == LEFT_MOTOR_ID) {
        eflash->write_eeprom_byte_data(start_addr, foc_param.L_FOC_PARM.storage_flag);
        start_addr += 1;
        eflash->write_eeprom_byte_data(start_addr, foc_param.L_FOC_PARM.Pole_Pair);
        start_addr += 1;
        eflash->write_eeprom_byte_data(start_addr, foc_param.L_FOC_PARM.motor_rotate_direct);
        start_addr += 1;
        eflash->write_eeprom_word_data(start_addr,foc_param.L_FOC_PARM.mechanical_offset.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr,foc_param.L_FOC_PARM.UqUd_Limit_Max.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr,foc_param.L_FOC_PARM.IqId_Limit_Max.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr, foc_param.L_FOC_PARM.Iq_P.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr, foc_param.L_FOC_PARM.Iq_I.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr, foc_param.L_FOC_PARM.Id_P.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr, foc_param.L_FOC_PARM.Id_I.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr, foc_param.L_FOC_PARM.Speed_P.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr, foc_param.L_FOC_PARM.Speed_I.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr, foc_param.L_FOC_PARM.Position_P.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr, foc_param.L_FOC_PARM.Position_I.u32_data);
    }
    else if( sel_M == RIGHT_MOTOR_ID) {
        start_addr = PARAMETER_FOC_STORAGE_BASE_ADDR + sizeof(foc_param.L_FOC_PARM);
        eflash->write_eeprom_byte_data(start_addr, foc_param.R_FOC_PARM.storage_flag);
        start_addr += 1;
        eflash->write_eeprom_byte_data(start_addr, foc_param.R_FOC_PARM.Pole_Pair);
        start_addr += 1;
        eflash->write_eeprom_byte_data(start_addr, foc_param.R_FOC_PARM.motor_rotate_direct);
        start_addr += 1;
        eflash->write_eeprom_word_data(start_addr,foc_param.R_FOC_PARM.mechanical_offset.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr,foc_param.R_FOC_PARM.UqUd_Limit_Max.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr,foc_param.R_FOC_PARM.IqId_Limit_Max.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr, foc_param.R_FOC_PARM.Iq_P.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr, foc_param.R_FOC_PARM.Iq_I.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr, foc_param.R_FOC_PARM.Id_P.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr, foc_param.R_FOC_PARM.Id_I.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr, foc_param.R_FOC_PARM.Speed_P.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr, foc_param.R_FOC_PARM.Speed_I.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr, foc_param.R_FOC_PARM.Position_P.u32_data);
        start_addr += 4;
        eflash->write_eeprom_word_data(start_addr, foc_param.R_FOC_PARM.Position_I.u32_data);
    }
    usb_printf("foc param save ok !\r\n");
}


Firmware_PARAMETER_STORAGE Aurora_Font::Load_Firmware_Parameter(){
    Firmware_PARAMETER_STORAGE param;
    eflash->read_data(PARAMETER_Firmware_STORAGE_BASE_ADDR,(uint8_t *)&param,sizeof(Firmware_PARAMETER_STORAGE));
    return param;
}
void Aurora_Font::Save_Firmware_Parameter(Firmware_PARAMETER_STORAGE firmware_param){
    eflash->write_eeprom_byte_data(PARAMETER_FOC_STORAGE_BASE_ADDR + 0,firmware_param.main_version);
    eflash->write_eeprom_byte_data(PARAMETER_FOC_STORAGE_BASE_ADDR + 1,firmware_param.minor_version);
    eflash->write_eeprom_word_data(PARAMETER_FOC_STORAGE_BASE_ADDR + 2,firmware_param.firmware_size);

}